package com.sun.dream.fish.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sun.dream.fish.entity.TUserEntity;
import com.sun.dream.fish.mapstruct.UserMapBasic;
import com.sun.dream.fish.mvc.exception.DSFException;
import com.sun.dream.fish.service.ILoginService;
import com.sun.dream.fish.service.TUserService;
import com.sun.dream.fish.util.CommonUtil;
import com.sun.dream.fish.util.MD5Util;
import com.sun.dream.fish.util.RandomNameUtil;
import com.sun.dream.fish.util.ResponseUtil;
import com.sun.dream.fish.vo.ResultVO;
import com.sun.dream.fish.vo.back.LoginUserVO;
import com.sun.dream.fish.vo.back.RegisterVO;
import com.sun.dream.fish.vo.back.UserVO;
import io.micrometer.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * Description:
 * Created By ljl on 2023/12/11.
 */
@Service
@Slf4j
public class LoginServiceImpl implements ILoginService {
    @Autowired
    TUserService userService;
    @Autowired
    ApplicationContext applicationContext;

    @Override
    public ResultVO<UserVO> register(RegisterVO registerVO) {
        if (StringUtils.isBlank(registerVO.getUsername())) {
            throw new DSFException("请输入用户名");
        }
//        if (){
//            throw new DSFException("验证码错误");
//        }

        if (!CommonUtil.isValidPhoneNumber(registerVO.getPhoneNumber())) {
            throw new DSFException("电话号码错误");
        }
        if (StringUtils.isBlank(registerVO.getPassword())) {
            throw new DSFException("请输入密码");
        }
        if (StringUtils.isBlank(registerVO.getConfirmPwd()) || !registerVO.getConfirmPwd().equals(registerVO.getPassword())) {
            throw new DSFException("确认密码不一致");
        }

        if (userService.checkUserExist(registerVO.getUsername(), registerVO.getPhoneNumber())) {
            throw new DSFException("用户已经存在,请换一个名字");
        }

        TUserEntity tUserEntity = new TUserEntity();
        tUserEntity.setUsername(registerVO.getUsername());
        tUserEntity.setPassword(MD5Util.encrypt(registerVO.getPassword()));
        tUserEntity.setName(MD5Util.encrypt(registerVO.getName()));
        tUserEntity.setCreatorId(0);
        tUserEntity.setTelephone(registerVO.getPhoneNumber());
        tUserEntity.setUserId(MD5Util.encrypt(registerVO.getUsername() + registerVO.getPassword()));
        if (StringUtils.isBlank(tUserEntity.getName())) {
            tUserEntity.setName(RandomNameUtil.getCombinedRandom());
        }
        return userService.save(tUserEntity) ? ResponseUtil.ok("注册成功") : ResponseUtil.fail("注册失败");
    }

    @Override
    public ResultVO<LoginUserVO> login(String username, String password) {
        //获取主体
        Subject subject = SecurityUtils.getSubject();
        try {
            if (!subject.isAuthenticated()) {
                subject.login(new UsernamePasswordToken(username, password));
                LambdaUpdateWrapper<TUserEntity> update = Wrappers.lambdaUpdate();
                update.eq(TUserEntity::getUsername, username);
                update.set(TUserEntity::getStatus, 1);
                update.set(TUserEntity::getLastLoginTime, LocalDateTime.now());
                ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                Objects.requireNonNull(servletRequestAttributes, "异常的登录请求！！！");
                update.set(TUserEntity::getLastLoginIp, servletRequestAttributes.getRequest().getRemoteAddr());
                userService.update(update);
            } else {
                TUserEntity principal = (TUserEntity) subject.getPrincipal();
                return ResponseUtil.ok(new LoginUserVO((String) subject.getSession().getId(), principal), "用户已登录");
            }
        } catch (UnknownAccountException e) {
            return ResponseUtil.fail("账号不存在");
        } catch (IncorrectCredentialsException e) {
            return ResponseUtil.fail("账号或密码不正确");
        } catch (Exception e) {
            log.error("[ILoginService]异常, ", e);
            return ResponseUtil.fail();
        }
        TUserEntity principal = (TUserEntity) subject.getPrincipal();
        return ResponseUtil.ok(new LoginUserVO((String) subject.getSession().getId(), principal), "登录成功");
    }

    @Override
    public ResultVO<LoginUserVO> logout() {
        Subject currentUser = SecurityUtils.getSubject();
        currentUser.logout();
        return ResponseUtil.ok("已登出");
    }
}
